ZK CRUD Demo Application
Stuart Charles
June 4 ,2007
Applicable to ZK 2.3.1
Introduction
CRUD interfaces are the bread and butter of everyday programming and are an essential part of most applications today but they can become tiresome and time consuming to build. This demo application has been built to demonstrate how data binding can be so useful in day to day programming, cutting out a lot of the dog work usually required for such interfaces. I have chosen a User/Role type structure as this is probably common across most applications which should make the code easier to understand.
The Demo Application is built in ZK 2.3.1, and uses Hibernate and Spring for interfacing with the database. The database SQL supplied is for MySQL 5 but the two tables are very simple so it could be easily recreated in any RDBMS, by switching the "hibernate.dialect" tag in applicationContext.xml
It is recommended to read ZK Developer's Reference: Data Binding before looking at this demo as this is essentially a practical extension of this small talk
Installation
Run the zkcruddemo.sql supplied into a MySQL 5 database. Alternatively change the database dialect in WEB-INF/applicationContext.xml and run the application to Let Hibernate create the database structure, mking sure the username and password is correct for your database. You might want to manually insert a couple of Roles first.
INSERT INTO `role` VALUES (1, 'Administrator', 'System Administrator', 1, 1);
INSERT INTO `role` VALUES (2, 'User', 'General User', 0, 0);
Structure
There are only two .zul files included in this application, one which lists all the users in the database and another that enables the user to add/edit a specific user. Each of these zul files have two Java Classes behind them, one to Initiate the object to be databound (the initiator) and the other is an extention of the Window class which handles all the events on that page
Walk Through
The loading of index.zul when the application starts triggers the ManageUsersInitiator class into action which loads the list of users from the database. This is a very simple class that loads the list of users into the page Attribute
public void doAfterCompose(Page page) {
UserHelper objUserHelper = (UserHelper) SpringUtil.getBean("userHelperManager");
page.setVariable("userList", objUserHelper.getAllUsers());
super.doAfterCompose(page);
}
Note that there is an "arg0" parameter supplied to the Initiator. This is required where there is more than one Databinder running on the ZK desktop at the same time. I just use the name of the Window to uniquely identify it
<?init class="zkcruddemo.ui.user.ManageUsersInitiator" arg0="manageUsersWindow"?>
The List loaded from the Initiator is then rendered in the display using the databinding tags in index.zul
<a:bind model="userList" selectedItem="manageUsersWindow.user"/>
<listbox mold="paging" id="usersListbox">
<listhead sizable="true" >
<listheader label="ID"/>
<listheader label="Username"/>
<listheader label="First Name"/>
<listheader label="Last Name"/>
<listheader label="Email"/>
<listheader label="User Group"/>
</listhead>
<a:bind _var="thisUser"/>
<listitem onDoubleClick="manageUsersWindow.onEditUser()">
<a:bind label="thisUser.id"/>
<listcell/>
<a:bind label="thisUser.userName"/>
<listcell/>
<a:bind label="thisUser.firstName"/>
<listcell/>
<a:bind label="thisUser.lastName"/>
<listcell/>
<a:bind label="thisUser.email"/>
<listcell/>
<a:bind label="thisUser.role.roleName"/>
<listcell/>
</listitem>
</listbox>
The important things here are:
- model="userList" is the name of the list of users loaded into the Page Variable from within the initiator.
- selectedItem="manageUsersWindow.user" is the selected item object that can retrieved from the Window class at any time
- _var="thisUser" is an arbitary value used for the current object being rendered so the name isn't too important
The events are then triggered by the buttons at the bottom of index.zul within the ManageUsersWindow Java class. The current selected item is easily picked up by calling getUser() in the Window and this is supplied to the EditUserWindow within a parameter Map using the Executions.createComponent command and executed as a Model window. The EditUserInitiator detects whether its a new or exisiting user and puts the User object in the Page Variable so it can be read by the EditUserWindow databinding declarations. The edituser.zul page works in exactly the same way as before.
Once a User has been added/updated, the List of User objects in the listbox needs to be cleared and reloaded again from the database. This is done in the ManageUserWindow by retriving the list of users in the listbox model and casting it as List:
public void refreshUsersListbox()
{
Listbox usersListbox = (Listbox)this.getFellow("usersListbox");
List userList = (List)usersListbox.getModel();
userList.clear();
userList.addAll(objUserHelper.getAllUsers());
}
The Listbox will then refresh. Deleting a user is even simpler using databinding as the user is retrieved using the getUser() method in the ManageUsersWindow and passed into the Spring Class that removes a user object from the database.
Summary
Databinding has huge benefits, reducing the time it takes to develop new applications considerably, and is great for scalability when it comes to adding new fields. It also cuts down the amount of reptitive programming tasks which every developer quickly tires of, leaving them more time to work on the cool stuff.
Download the source code here
Stuart Charles is a Software Developer working for Telstra International in the UK. He has a degree in Business Information Systems and has around three years J2EE development experience, focusing on frameworks such as Hibernate, Spring, Struts and now ZK.
Copyright © Stuart Charles. This article is licensed under GNU Free Documentation License. |